﻿using System;
using System.Collections.Generic;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.ServiceModel.Interfaces;
using StockholmsStad.Business;
using StockholmsStad.Utilities.Exceptions;
using System.ServiceModel;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;

namespace StockholmsStad.ServiceModel.Services
{
    /// <summary>
    /// Detta är serviceimplementationsklassen för servicen IMaintenanceService.
    /// </summary>
    public class MaintenanceService : IMaintenanceService
    {
        //TODO Flytta alla metoder som har med Maintenance till denna tjänst

        #region IMaintenanceService Members

        /// <summary>
        /// Operationskontrakt som hämtar alla par som kan avpersonifieras.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="fromDate">Fråndatum</param>
        /// <param name="toDate">Tilldatum</param>
        /// <returns>En lista av typen <see cref="CouplesSummaryItem"/> med alla par som kan avpersonifieras.</returns>
        public IList<Couple> GetCouplesForDepersonation(User user, DateTime fromDate, DateTime toDate)
        {
            try
            {
                return new MaintenanceBusiness(user).GetCouplesForDepersonation(fromDate,toDate);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som hämtar alla par som kan avpersonifieras.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="couples">Fråndatum</param>
        /// <returns>En lista av typen <see cref="CouplesSummaryItem"/> med alla par som kan avpersonifieras.</returns>
        public int DepersonateCouples(User user, List<Couple> couples)
        {
            try
            {
                return new MaintenanceBusiness(user).DepersonateCouples(couples);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som hämtar databasens version.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En version <see cref="StockholmsStad.Data.Entity.Version"/></returns>
        public string GetDatabaseVersion(User user)
        {
            try
            {
                return new MaintenanceBusiness(user).GetDatabaseVersion();
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som hämtar tjänstelagrets version.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>Ett versionsnummer </returns>
        public string GetServiceVersion(User user)
        {
            try
            {
                return new MaintenanceBusiness(user).GetServiceVersion();
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som uppdaterar ett språk
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="language">Språket</param>
        /// <returns></returns>
        public void UpdateLanguage(User user, ValueIdPair language)
        {
            try
            {
                new MaintenanceBusiness(user).UpdateLanguage(language);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som tar bort ett språk
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="language">Språket</param>
        /// <returns></returns>
        public void DeleteLanguage(User user, ValueIdPair language)
        {
            try
            {
                new MaintenanceBusiness(user).DeleteLanguage(language);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som tar bort ett ceremoni språk
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="language">Språket</param>
        /// <returns></returns>
        public void DeleteCeremonyLanguage(User user, ValueIdPair language)
        {
            try
            {
                new MaintenanceBusiness(user).DeleteCeremonyLanguage(language);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Operationskontrakt som tar bort ett certifikat språk
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="language">Språket</param>
        /// <returns></returns>
        public void DeleteCertificateLanguage(User user, ValueIdPair language)
        {
            try
            {
                new MaintenanceBusiness(user).DeleteCertificateLanguage(language);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar all texter
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="textId">Den typ av text som ska hämtas. </param>
        /// <returns>En lista med texter (<see cref="InformationText"/>).</returns>
        public InformationText GetText(User user, int textId)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetText(textId);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar all texter
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="textTypeId">Den typ av text som ska hämtas. </param>
        /// <returns>En lista med texter (<see cref="InformationText"/>).</returns>
        public IList<InformationText> GetTexts(User user, int textTypeId)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetTexts(textTypeId);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar all texttyper
        /// </summary>
        /// <returns>En lista med texttyper (<see cref="ValueIdPair"/>).</returns>
        public IList<ValueIdPair> GetTextTypes(User user)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetTextTypes();
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Implementation av operationskontraktet för att lägga till en text. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="text">Den text som ska läggas till (<see cref="InformationText"/>). </param>
        /// <returns>Nyckeln på den tillagda texten. </returns>
        public int AddText(User user, InformationText text)
        {
            try
            {
                return new MaintenanceBusiness(user).AddText(text);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Implementation av operationskontraktet för att uppdatera text. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="text">Den text som ska uppdateras(<see cref="InformationText"/>). </param>
        public void UpdateText(User user, InformationText text)
        {
            try
            {
                new MaintenanceBusiness(user).UpdateText(text);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Implementation av operationskontraktet för att ta bort text. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="text">Den text som ska tas bort(<see cref="InformationText"/>). </param>
        public void DeleteText(User user, InformationText text)
        {
            try
            {
                new MaintenanceBusiness(user).DeleteText(text);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar alla tillgängliga språk för en viss typ av certifikat. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="certificateType">Anger vilken typ som tillgängliga språk finns för. </param>
        /// <returns>En lista med språk (<see cref="ValueIdPair"/>).</returns>
        public List<ValueIdPair> GetAvailableLanguagesForReportDefinition(User user, MarriageCertificateType certificateType)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetAvailableLanguagesForReportDefinition(certificateType);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar alla tillgängliga språk för en viss typ av certifikat. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="certificateType">Anger vilken typ som tillgängliga språk finns för. </param>
        /// <returns>En lista med språk (<see cref="ValueIdPair"/>).</returns>
        public List<ValueIdPair> GetLanguagesForCertificateType(User user, MarriageCertificateType certificateType)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetLanguagesForCertificateType(certificateType);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Skapar en ny rapportdefinition (en rapport med nytt språk och innehåll). 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="certificate">Innehållet på den nya rapportdefinitionen. </param>
        /// <returns>Id-numret på den tillagda rapportdefinitionen. </returns>
        public int AddMarriageCertificate(User user, MarriageCertificate certificate)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.AddMarriageCertificate(certificate);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Uppdaterar en befintlig rapportdefinition. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="certificate">Innehållet på rapportdefinitionen. </param>
        /// <returns> </returns>
        public void UpdateMarriageCertificate(User user, MarriageCertificate certificate)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                maintenanceBusiness.UpdateMarriageCertificate(certificate);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Tar bort en befintlig rapportdefinition. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="certificate">Innehållet på rapportdefinitionen. </param>
        /// <returns> </returns>
        public void DeleteMarriageCertificate(User user, MarriageCertificate certificate)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                maintenanceBusiness.DeleteMarriageCertificate(certificate);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar ett registreringsbevis. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="marriageCertificateType">Id-numret på det aktuella beviset. </param>
        /// <param name="languageId">Id-numret på det aktuella beviset. </param>
        /// <returns>Registreringsbeviset. </returns>
        public MarriageCertificate GetMarriageCertificate(User user, MarriageCertificateType marriageCertificateType, int languageId)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetMarriageCertificate(marriageCertificateType, languageId);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Hämtar befintliga affärsregler
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>De regler som gäller. </returns>
        public ParVisProperties GetProperties(User user)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetProperties();
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// Uppdaterar affärsregler. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="properties">De regler som ska uppdateras. </param>
        public void SetProperties(User user, ParVisProperties properties)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                maintenanceBusiness.SetProperties(properties);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public List<ValueIdPair> GetLanguages(User user)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.GetLanguages();
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public int AddSpecialNeed(User user, string name)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.AddSpecialNeed(name);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="languageName"></param>
        /// <returns></returns>
        public int AddLanguage(User user, string languageName)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.AddLanguage(languageName);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="languageName"></param>
        /// <returns></returns>
        public int AddCeremonyLanguage(User user, string languageName)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.AddCeremonyLanguage(languageName);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="languageName"></param>
        /// <returns></returns>
        public int AddCertificateLanguage(User user, string languageName)
        {
            try
            {
                var maintenanceBusiness = new MaintenanceBusiness(user);
                return maintenanceBusiness.AddCertificateLanguage(languageName);
            }
            catch (StockholmStadSystemException e)
            {
                throw new FaultException<StockholmStadSystemErrorFault>(new StockholmStadSystemErrorFault(e.ErrorCode, e.Message));
            }
            catch (StockholmStadApplicationException e)
            {
                throw new FaultException<StockholmStadApplicationErrorFault>(new StockholmStadApplicationErrorFault(e.ErrorCode, e.Message));
            }
        }

        #endregion
    }
}
